{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f57f9e21-c8f4-4141-b5c7-14ee7393394f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 安装软件包\n",
    "# !pip install opencv-python\n",
    "# !pip install opencv-contrib-python\n",
    "# !pip install paddlepaddle \n",
    "# !pip install paddleocr\n",
    "# !pip install tk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e227ffb1-f8fc-4976-8bea-3660cef56400",
   "metadata": {},
   "outputs": [],
   "source": [
    "# cap 用来获取摄像头\n",
    "global cap\n",
    "\n",
    "# frame 用来存储从摄像头拍摄的图片\n",
    "global frame\n",
    "\n",
    "# pieces 用来存储使用ocr模块检测得到的棋子中文名\n",
    "global pieces\n",
    "\n",
    "global result\n",
    "# result (int)：是一个整数,用来表示双方棋子比较大小的结果\n",
    "#     - -1: 表示输入错误.\n",
    "#     - 0: 表示双方打平.\n",
    "#     - 1: 表示 A 吃掉了 B.\n",
    "#     - 2: 表示 B 吃掉了 A.\n",
    "#     - 3: 表示 A 胜利.\n",
    "#     - 4: 表示 B 胜利.\n",
    "\n",
    "global flag\n",
    "# flag (dict): 是一个词典，表示 A、B 两方是否需要亮军旗。词典的keys是 \"a\"和\"b\"。\n",
    "#     - 0: 表示不需要亮军旗.\n",
    "#     - 1: 表示需要亮军旗.\n",
    "\n",
    "global ca, cb\n",
    "# 分别表示 A、B 两方的判决指示灯颜色。\n",
    "# 红色表示被吃掉。\n",
    "# 绿色表示没有被吃掉\n",
    "# 白色表示被吃掉，并且需要亮军旗。\n",
    "# 黄色表示最终胜利\n",
    "# 黑色表示最终失败\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "7524aa1e-4252-454a-ac2b-c0e9cb68f9d5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "from datetime import datetime\n",
    "import tkinter as tk\n",
    "import utils"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0ce1cab1-eedc-4359-a93e-c1722dd9efd1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "开始初始化摄像头\n",
      "完成初始化摄像头\n"
     ]
    }
   ],
   "source": [
    "############################\n",
    "# 初始化摄像头\n",
    "############################\n",
    "# 电脑自带摄像头是序号是 0\n",
    "# 外接usb摄像头是序号是 1\n",
    "print(\"开始初始化摄像头\")\n",
    "# 使用 cv2.CAP_DSHOW 选项，能提高初始化摄像头的速度\n",
    "cap = cv2.VideoCapture(1, cv2.CAP_DSHOW)\n",
    "print(\"完成初始化摄像头\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "f6982862-71ba-475d-a17b-8cce1ac65702",
   "metadata": {},
   "outputs": [],
   "source": [
    "def round_command():\n",
    "    \n",
    "    global frame, cap, pieces, result, flag\n",
    "\n",
    "    ############################\n",
    "    # 采集包含棋子的图像\n",
    "    ############################\n",
    "    # 如果只读一帧，读到的是缓存的图像，不是实时采集的。\n",
    "    # 所以在这里连续读2次。\n",
    "    frame = utils.capture(cap)\n",
    "    frame = utils.capture(cap)\n",
    "    \n",
    "    # Get the current timestamp and format it\n",
    "    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')  # Format: YYYYMMDD_HHMMSS        \n",
    "    # Define the filename with the timestamp\n",
    "    filename = f'image_{timestamp}.png'  # You can change the extension as needed\n",
    "    cv2.imwrite(filename, frame)\n",
    "    print(f\"save image to file {filename}\")\n",
    "\n",
    "    ############################\n",
    "    # 识别棋子上的文字\n",
    "    ############################\n",
    "    pieces = utils.ocr(frame)        \n",
    "    print(f\"识别到了棋子:{pieces}\")\n",
    "    if len(pieces) != 2:\n",
    "        print(f\"错误的输出结果。识别到的棋子个数不是2。\")     \n",
    "\n",
    "    ############################\n",
    "    # 棋子比大小\n",
    "    ############################\n",
    "    a, b = utils.get_ranks(pieces)   \n",
    "    result, flag = utils.compare(a,b)\n",
    "    print(f\"result:{result},flag:{flag}. (-1 error, 0 die, 1 a win, 2 b win, 3 a victory, 4 b victory)\")\n",
    "\n",
    "    ############################\n",
    "    # 显示判定结果\n",
    "    ############################\n",
    "    ca, cb = utils.get_color(result, flag)\n",
    "    print(f\"ca:{ca},cb:{cb}. (Red die, green win, white flag, yello victory, black lose )\")\n",
    "    utils.draw(ca, cb)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "16d15178-63ea-4757-841c-7896c916e29b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "save image to file image_20241201_152223.png\n",
      "识别到了棋子:['师长', '军长']\n",
      "a:7, b:8\n",
      "result:2,flag:{'a': 0, 'b': 0}. (-1 error, 0 die, 1 a win, 2 b win, 3 a victory, 4 b victory)\n",
      "ca:(0, 0, 255),cb:(0, 255, 0). (Red die, green win, white flag, yello victory, black lose )\n"
     ]
    }
   ],
   "source": [
    "\n",
    "# Create the main window\n",
    "root = tk.Tk()\n",
    "root.title(\"Hello World App\")\n",
    "\n",
    "# run a round\n",
    "round_button = tk.Button(root, text=\"round\", command=round_command)\n",
    "round_button.pack(pady=20)\n",
    "\n",
    "# Run the application\n",
    "root.mainloop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "feda7cab-5820-40ee-8126-922a58e66168",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<function __main__.release_camera()>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "# Release resources when done (to be called later)\n",
    "def release_camera():\n",
    "    cap.release()\n",
    "    cv2.destroyAllWindows()\n",
    "\n",
    "import atexit\n",
    "atexit.register(release_camera)  # Ensure camera is released on exit\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f3c146a2-25bb-4411-ac1b-d459373a9b3e",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
